﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AddIn.EA.Architecture.ComponentLogic.ElementModel;

namespace AddIn.EA.Architecture.ComponentLogic.StandardProject.Builders.UI
{
    public class ElementBuilderPresenter : ElementBuilder
    {
        public override void BuildStructure(AddIn.EA.Architecture.ComponentLogic.ElementModel.Package viewModel, AddIn.EA.Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            BuildPresenterElement(viewModel, templateRepository, itemEntity);
            BuildPresenterInterfaceElement(viewModel, templateRepository, itemEntity);
        }
        public void BuildPresenterElement(ComponentLogic.ElementModel.Package viewModel, Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            AddIn.EA.Framework.Package templatePackage = GetTemplatePackage(templateRepository);
            AddIn.EA.Framework.Element templatePresenterElement = templatePackage.GetElementByName("[entity_name]");

            ComponentLogic.ElementModel.Package PresenterPackage = GetPresenterPackage(viewModel);

            String elementName = templatePresenterElement.Name.Replace("[entity_name]", itemEntity.Name);
            //Prevent existing item before include
            PresenterPackage.Elements.RemoveAll(it => it.Name.CompareTo(elementName) == 0);

            //Build Presenter attributes.
            Element PresenterElement = BuildEntityElementFromTemplate(itemEntity, templatePresenterElement, elementName);
            PresenterElement.Attributes.ForEach(it => it.Type = it.Type.Replace("List<", "ModelCollection<"));

            BindElementMethods(PresenterElement, itemEntity, "Model", "Model");
            foreach (ElementModel.Method itemMethod in PresenterElement.Methods)
            {
                itemMethod.Parameters = itemMethod.Parameters.Replace("List<", "ModelCollection<");
                itemMethod.Return = itemMethod.Return.Replace("List<", "ModelCollection<");
            }

            //Create standard objects instances for Presenter.
            if (itemEntity.HasFilter)
                PresenterElement.Attributes.Add(new AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute
                {
                    Encapsulate = false,
                    Name = "_filtro" + itemEntity.Name,
                    Scope = Scope.Private,
                    Type = "Model.Parameter.Filtro" + itemEntity.Name
                });
            if (itemEntity.HasKeyFilter)
                PresenterElement.Attributes.Add(new AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute
                {
                    Encapsulate = false,
                    Name = "_filtro" + itemEntity.Name + "Chave",
                    Scope = Scope.Private,
                    Type = "Model.Parameter.Filtro" + itemEntity.Name + "Chave"
                });
            PresenterElement.Attributes.Add(new AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute
            {
                Encapsulate = false,
                Name = "_" + itemEntity.Name.Substring(0, 1).ToLowerInvariant() + itemEntity.Name.Substring(1, itemEntity.Name.Length - 1),
                Scope = Scope.Private,
                Type = "Model." + itemEntity.Name
            });
            PresenterElement.Attributes.Add(new AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute
            {
                Encapsulate = false,
                Name = "_" + itemEntity.Name.Substring(0, 1).ToLowerInvariant() + itemEntity.Name.Substring(1, itemEntity.Name.Length - 1) + "s",
                Scope = Scope.Private,
                Type = "ModelCollection<Model." + itemEntity.Name + ">"
            });
            PresenterElement.Attributes.Add(new AddIn.EA.Architecture.ComponentLogic.ElementModel.Attribute
            {
                Encapsulate = false,
                Name = "_communication" + itemEntity.Name,
                Scope = Scope.Private,
                Type = "Communication." + itemEntity.Name
            });

            PresenterPackage.Elements.Add(PresenterElement);
        }
        public void BuildPresenterInterfaceElement(ComponentLogic.ElementModel.Package viewModel, Framework.RepositoryManager templateRepository, BusinessEntityStandardProject itemEntity)
        {
            AddIn.EA.Framework.Package templatePackage = GetTemplatePackage(templateRepository);

            AddIn.EA.Framework.Element templatePresenterInterface = templatePackage.GetElementByName("I[entity_name]");

            //Setup the BusinessEntity package
            ComponentLogic.ElementModel.Package PresenterPackage = GetPresenterPackage(viewModel);

            String elementInterfaceName = templatePresenterInterface.Name.Replace("[entity_name]", itemEntity.Name);

            //Prevent existing item before include
            PresenterPackage.Elements.RemoveAll(it => it.Name.CompareTo(elementInterfaceName) == 0);

            //Build PresenterInterface attributes.
            Element PresenterInterfaceElement = BuildEntityElementFromTemplate(itemEntity, templatePresenterInterface, elementInterfaceName);
            PresenterInterfaceElement.Type = ElementType.Interface;
            PresenterInterfaceElement.Attributes.ForEach(it => it.Type = it.Type.Replace("List<", "ModelCollection<"));

            PresenterPackage.Elements.Add(PresenterInterfaceElement);
        }
        private Framework.Package GetTemplatePackage(Framework.RepositoryManager templateRepository)
        {
            return templateRepository.GetPackageByName("UI").GetPackageByName("Presenter");
        }
        private Package GetPresenterPackage(ComponentLogic.ElementModel.Package viewModel)
        {
            ComponentLogic.ElementModel.Package uiPackage = GetViewModelPackage("UI", viewModel, true);
            ComponentLogic.ElementModel.Package PresenterPackage = GetViewModelPackage("Presenter", uiPackage, true);
            return PresenterPackage;
        }

        public override void Validate()
        {
        }
    }
}
